﻿using LNamePipe;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HCLSMod.NamePipe
{
    public delegate void NamePipeCommandEventCallBack(object sender,ref NamePipeCommandBase fCommand);

    public class NPServerNode: NPServerSocket
    {
        public NamePipeCommandEventCallBack OnRecCommand;

        protected void RunOnRecCommand(object sender,ref NamePipeCommandBase fCommand)
        {
            if (OnRecCommand != null)
                OnRecCommand(sender,ref fCommand);
        }

        public DateTime fLastRec = DateTime.Now;
        /// <summary>
        ///  最后收到数据事件
        /// </summary>
        public DateTime LastRec { get { return fLastRec; } }
        /// <summary>
        /// 客户端连接的GUID
        /// </summary>
        protected string fClientToken = "";
                /// <summary>
        /// 客户端连接的GUID，无客户端连接时为空
        /// </summary>
        public string ClientToken
        {
            get
            {
                if (this.Connected)
                    return fClientToken;
                else
                    return "";
            }
        }

        public NPServerNode() : this(DefaultPipeName)
        { }

        public NPServerNode(string fPNName) : base(fPNName)
        { }
        /// <summary>
        /// 用专用命令包打包接收发送数据基础函数
        /// </summary>
        /// <param name="fRTDatas">要发送或接收的数据，成功处理返回处理结果</param>
        /// <param name="AnalyseType">分析类型</param>
        /// <returns>成功处理返回真</returns>
        protected override bool AnalyseRTDatas(ref byte[] fRTDatas, TAnalyseDatasType AnalyseType)
        {
            Guid fUToken;
            Guid fCToken;
            NamePipeCommandBase fRTCommand = null;
            fRTDatas = null;
            bool fResult = false;
            try
            {
                fRTCommand = (NamePipeCommandBase)BaseLib.DeserializeObject(fRTDatas);
                
                if ((fRTCommand!=null)
                    &&(!string.IsNullOrEmpty(fRTCommand.UserToken))
                    && Guid.TryParse(fRTCommand.UserToken,out fUToken)
                    && (!string.IsNullOrEmpty(fRTCommand.CommandToken))
                    && Guid.TryParse(fRTCommand.CommandToken, out fCToken))
                {
                    switch(AnalyseType)
                    {
                        case TAnalyseDatasType.ADT_SerRec:
                            fLastRec = DateTime.Now;
                            fClientToken = fUToken.ToString().ToUpper();
                            RunOnRecCommand(this,ref fRTCommand);
                            break;
                        case TAnalyseDatasType.ADT_SerAnswer:
                            fRTCommand.IsRespon = true;
                            break;                            
                    }
                    if (fRTCommand != null)
                        fRTDatas = BaseLib.SerializeObject(fRTCommand);
                    else
                        fRTDatas = null;
                    fResult = true;
                }
            }
            catch (Exception ex)
            {
                ErrorRecord.PutErrorEvent(ex);
                fResult = false;
            }
            return fResult;
        }
        protected override void RunOnDisconnect()
        {
            fClientToken = "";
        }
    }

    public class NPClientNode:NPClientSocket
    {
        public NamePipeCommandEventCallBack OnRecCommand;

        protected void RunOnRecCommand(object sender,ref NamePipeCommandBase fCommand)
        {
            if (OnRecCommand != null)
                OnRecCommand(sender, ref fCommand);
        }

        public NPClientNode() : base()
        { }

        public NPClientNode(string fNPName): base(fNPName)
        { }

        public NPClientNode(string fSerIP, string fNPName):base( fSerIP,  fNPName)
        { }

        public NPClientNode(string fSerIP, string fNPName, int fNewRecBufSize):base( fSerIP,  fNPName,  fNewRecBufSize)
        { }

        /// <summary>
        /// 用专用命令包打包接收发送数据基础函数
        /// </summary>
        /// <param name="fRTDatas">要发送或接收的数据，成功处理返回处理结果</param>
        /// <param name="AnalyseType">分析类型</param>
        /// <returns>成功处理返回真</returns>
        protected override bool AnalyseRTDatas(ref byte[] fRTDatas, TAnalyseDatasType AnalyseType)
        {
            Guid fUToken;
            Guid fCToken;
            NamePipeCommandBase fRTCommand = null;
            bool fResult = false;
            try
            {
                fRTCommand = (NamePipeCommandBase)BaseLib.DeserializeObject(fRTDatas);

                if ((fRTCommand != null)
                    && (!string.IsNullOrEmpty(fRTCommand.UserToken))
                    && Guid.TryParse(fRTCommand.UserToken, out fUToken)
                    && (!string.IsNullOrEmpty(fRTCommand.CommandToken))
                    && Guid.TryParse(fRTCommand.CommandToken, out fCToken))
                {
                    switch (AnalyseType)
                    {
                        case TAnalyseDatasType.ADT_CliSend:
                            break;
                        case TAnalyseDatasType.ADT_CliRec:
                            RunOnRecCommand(this,ref fRTCommand);
                            break;
                    }
                    if (fRTCommand != null)
                        fRTDatas = BaseLib.SerializeObject(fRTCommand);
                    else
                        fRTDatas = null;
                    fResult = true;
                }
            }
            catch (Exception ex)
            {
                ErrorRecord.PutErrorEvent(ex);
                fResult = false;
            }
            return fResult;
        }

        /// <summary>
        /// 向目标命名管道发送命令，为确保名利的Token为本对象的Token，函数为内部命令，
        /// </summary>
        /// <param name="fSendData"></param>
        /// <returns></returns>
        protected int SendData(NamePipeCommandBase fCommand)
        {
            int fResult = 0;
            if (IsConnected && (fCommand != null))
            {
                byte[] fSendData = null;
                try
                {
                    fSendData = BaseLib.SerializeObject(fCommand);
                    if ((fSendData != null) && (fSendData.Length > 0))
                        fResult= SendData(fSendData);
                }
                catch (Exception ex)
                {
                    ErrorRecord.PutErrorEvent(ex);
                }
            }
            return fResult;                
        }
        /// <summary>
        /// 以命令方式发送数据
        /// </summary>
        /// <param name="fIdxMain"></param>
        /// <param name="fIdxSub"></param>
        /// <param name="fSendData"></param>
        /// <returns></returns>
        public int SendData(int fIdxMain, int fIdxSub,  byte[] fSendData)
        {
            NamePipeCommandBase fCommand = new NamePipeCommandBase(fUserToken);
            fCommand.IndexMain = fIdxMain;
            fCommand.IndexSub = fIdxSub;
            fCommand.CommandData = fSendData;
            return SendData(fCommand);
        }
    }

    public class NPNodesService : NPService
    {
        /// <summary>
        /// 接收到命令事件
        /// </summary>
        public NamePipeCommandEventCallBack OnRecCommand;

        protected void RunOnRecCommand(object sender,ref NamePipeCommandBase fCommand)
        {
            if (OnRecCommand != null)
                OnRecCommand(sender, ref fCommand);
        }       

        public NPNodesService():base()
        { }
        public NPNodesService(string fNamePipe):base (fNamePipe)
        { }

        /// <summary>
        /// 重载：创建新的服务接口
        /// </summary>
        /// <returns></returns>
        protected override NPServerSocket fCreateNewNPSer()
        {
            if (!string.IsNullOrEmpty(fPipeName))
            {
                NPServerNode fNPSer = new NPServerNode(fPipeName);
                fNPSer.OnRecCommand += FNPSer_OnRecCommandData;
                return fNPSer;
            }
            return null;
        }       

        private void FNPSer_OnRecCommandData(object sender,ref NamePipeCommandBase RecCommand)
        {
            RunOnRecCommand(sender,ref RecCommand);
        }
        /// <summary>
        /// 根据提供的客户端Token，提取对应连接的服务接口
        /// </summary>
        /// <param name="fCliToken"></param>
        /// <returns></returns>
        public NPServerNode GetSerNodeByCliToken(string fCliToken)
        {
            Guid fCToken;
            NPServerNode fResult = null;
            if ((!string.IsNullOrEmpty(fCliToken))
                && Guid.TryParse(fCliToken, out fCToken)
                && fNamePipeList.Count > 0)
                for (int i = 0; i < fNamePipeList.Count; i++)
                {
                    NPServerNode fTemp =  (NPServerNode)(fNamePipeList[i]);
                    if (fCToken.ToString().ToUpper().Equals(fTemp.ClientToken))
                    {
                        fResult = fTemp;
                        break;
                    }
                }
            return fResult;
        }        
    }
}
